package com.iakuil.app.common.db;

import com.github.pagehelper.parser.SqlParser;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParser;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.Statement;

import java.util.concurrent.*;

/**
 * 可配置超时时间的SqlParser
 *
 * <p>适配PageHelper插件，默认5秒超时。
 *
 * @author Kai
 */
public class TimeoutSqlParser implements SqlParser {

    ExecutorService timeOutService = Executors.newWorkStealingPool(Runtime.getRuntime().availableProcessors() * 2);

    @Override
    public Statement parse(String sql) throws JSQLParserException {
        // JSqlParser 4.8以后可以直接传入timeOutService
        CCJSqlParser parser = CCJSqlParserUtil.newParser(sql);
        parser.withSquareBracketQuotation(true);
        Statement statement;
        Future<Statement> future = timeOutService.submit(parser::Statement);
        try {
            statement = future.get(50000, TimeUnit.MILLISECONDS);
            return statement;
        } catch (TimeoutException te) {
            parser.interrupted = true;
            future.cancel(true);
            throw new JSQLParserException("Time out occurred.", te);
        } catch (Exception ex) {
            throw new JSQLParserException(ex);
        }
    }
}
